package com.example.kotlindemo.demo

/**
 * Author:zs
 *Date:2022/8/17 11:08
 *
 *Unit4 循环控制
 *describe：
 * 1.for循环
 * 2.while和do...while...
 **/
class Unit4 {
    var arr: Array<String> = arrayOf("a", "b", "c", "d", "e")

    /**
     * 一、for循环
     * 1.for可以对任何迭代器的对象进行遍历
     */
    fun testArray() {
        //for循环
        for (i in arr) {
            println(i)
        }
        for (i: String in arr) {
            println(i)
        }
        //通过索引遍历
        for (i in arr.indices) {
            println(arr[i])
        }
        //在区间上遍历
        for ((index, value) in arr.withIndex()) {
            println("current index is $index and value is $value")
        }
    }

    /**
     * 二、while 与 do...while 循环
     */
    fun testWhile() {
        var iterator = arr.iterator()
        while (iterator.hasNext()) {
            println(iterator.next())
        }
        //do..while..
        var iterator1 = arr.iterator()
        do {
            println(iterator1.next())
        } while (iterator1.hasNext())
    }

    /**
     * 三、返回和跳转
     * 1.return：默认从包围他的函数或者匿名函数返回
     * 2.break：终止最直接包围它的循环
     * 3.continue：继续下一次最直接的循环
     */
    var demo1: (Int, String) -> Unit = { x, y -> println("index:$x value:$y") }
    fun testJump() {
        for (i in arr) {//默认从包围他的函数或者匿名函数返回
            println("break:$i")
            if (i == "c") {
                break
            }

        }
        for (i in arr) {//继续下一次最直接的循环
            println("continue:$i")
            if (i == "d") {
                continue
            }

        }
        for ((index, value) in arr.withIndex()) {
            demo1(index, value)
        }
        for (i in arr) {//终止最直接包围它的循环
            println("return:$i")
            if (i == "d") {
                return
            }
        }

    }

    /**
     * 四、Break 和 Continue 标签
     * 1.在Kotlin中任何的表达式都可以通过标签来标记，格式，标识符后面添加@符号，例如abc@、test@
     */
    fun testLable() {
        var array = Array<Int>(10,{x->x*2})
        point@ for (i in 1..5) {
//            println("#################分割符$i#################")
            for (i in 1..5) {
//                println("$i")
                 if (i==4)continue@point
            }
        }
        println("#################分割符#################")
        arr.forEach lit@{
            println(it)
            if (it == "c"){
                return@lit
            }
        }
    }
    /**
     * 返回标签处
     * 1.Kotlin有函数字面量，局部函数和对象表达式。因此Kotlin的函数可以嵌套。标签限制的return允许我们从外层函数返回。、
     * 最重要的一个用途就是从lambda表达式中返回。
     */
    fun testReturn(){
        arr.forEach {
            if (it == "d") return@forEach //函数会返回到forEach循环中继续执行下一次的循环
            println(it) //打印结果 "a" "b" "c" "e"
        }
    }
    //使用匿名函数替代,匿名函数的内部return语句将从改匿名函数自身返回
    fun testUnknown(){
        println("testUnKnown")
        arr.forEach(
            fun (str:String){
            if (str == "d"){
                return//返回匿名函数自身，forEach循环继续执行。
            }
            println(str)
        })
    }


}